home *** CD-ROM | disk | FTP | other *** search
/ Games of Daze / Infomagic - Games of Daze (Summer 1995) (Disc 1 of 2).iso / x2ftp / msdos / source / xcode / cpcc.c < prev    next >
Encoding:
C/C++ Source or Header  |  1993-11-22  |  10.8 KB  |  365 lines

  1. /*----------------------------------------------------------------------------
  2.     "CPCC.C" - A routine to compile a sprite stored in a PCC file
  3.                                             (C) John Connors 1993
  4. ----------------------------------------------------------------------------*/
  5.  
  6. #include <stdio.h>
  7. #include <mem.h>
  8. #include <alloc.h>
  9. #include <string.h>
  10. #include <stdlib.h>
  11.  
  12. #define FALSE (0)
  13. #define TRUE  (-1)
  14.  
  15. /*----------------------------------------------------------------------------
  16.  The header of a .PCX or .PCC file                                         
  17. ----------------------------------------------------------------------------*/
  18.  
  19. typedef struct pcc_s
  20. {
  21.     unsigned char id;
  22.     unsigned char version;
  23.     unsigned char encoding_mode;
  24.     unsigned char bits_per_pixel;
  25.     int           x1;            
  26.     int           y1;   
  27.     int           x2;        
  28.     int           y2;        
  29.     int           horizontal_resolution;
  30.     int           vertical_resolution;
  31.     unsigned char colour_map[48];   
  32.     unsigned char not_used;     
  33.     unsigned char number_of_planes;
  34.     unsigned int  bits_per_plane_line;
  35.     unsigned int  palette_information;
  36.     unsigned int  source_x_resolution;
  37.     unsigned int  source_y_resolution;
  38.     unsigned char extra[54];
  39. } pcc_header; /* pcc_s */
  40.  
  41. /*----------------------------------------------------------------------------
  42.     Linear bit map header
  43. ----------------------------------------------------------------------------*/
  44.  
  45. typedef struct lbm_s
  46. {
  47.     unsigned int width;
  48.     unsigned int height;
  49. } lbm_header;
  50.  
  51. /*----------------------------------------------------------------------------
  52.    Assembler functions callled by cpcc.c
  53. ----------------------------------------------------------------------------*/
  54.  
  55. extern unsigned int get_file(char far *file_name,char far *file_buffer);
  56. extern unsigned int get_file_size(char far *file_name);
  57.  
  58. extern void decode_pcx_buffer(void far *destination,void far *source);
  59.  
  60. extern void fix_odd_width_bug(lbm_header *buffer);
  61.  
  62. extern unsigned int separate_sprite_plane(unsigned char far *source,
  63.                                           unsigned char far *destination,
  64.                                           unsigned int plane);
  65.                                           
  66. /*----------------------------------------------------------------------------
  67.     Global variable declarations
  68. ----------------------------------------------------------------------------*/
  69.  
  70. char far *file_buffer;
  71. pcc_header far *pcc_buffer;
  72. lbm_header far *lbm_buffer;
  73.  
  74. char pcc_name[128];
  75. char cbm_name[128];
  76.  
  77. unsigned int pcc_size;
  78. unsigned int lbm_size;
  79. unsigned int cbm_size;
  80.  
  81. unsigned char far *sprite_planes[4];
  82. unsigned int plane_width[4];
  83. unsigned int sprite_width;
  84. unsigned int sprite_height;
  85. unsigned char far *sprite_byte;
  86. unsigned int sprite_plane;
  87.  
  88. unsigned int lbm_width;
  89. unsigned char far *lbm_byte;
  90.  
  91. unsigned int si_bump;
  92.  
  93. unsigned long eax_contents;                     /* keep track of eax */
  94. int eax_dirty;
  95.  
  96. FILE *cbm_file;
  97.  
  98. /*----------------------------------------------------------------------------
  99.    Remove the file type suffix
  100. ----------------------------------------------------------------------------*/
  101.  
  102. char *remove_suffix(char *file_name)
  103. {
  104.     int l;
  105.     char far *name;
  106.     
  107.     name = strdup(file_name);     
  108.     l = strlen(name);
  109.     if ((l>=3) && (name[l-3]=='.'))
  110.     {
  111.         name[l-3] = '\0';
  112.     }
  113.     name = strlwr(name);
  114.     return name;
  115. } /* remove_suffix() */
  116.  
  117. /*----------------------------------------------------------------------------
  118.     Open the output file
  119. ----------------------------------------------------------------------------*/
  120.  
  121. FILE  *open_out(char far *filename)
  122. {
  123.     FILE *f;
  124.     
  125.     f = fopen(filename,"wt"); 
  126.     
  127.     if (f==NULL)
  128.     {
  129.         fprintf(stderr,"unable to open %Fs for writing\n",filename);
  130.         exit(0);
  131.     }
  132.     
  133.     fprintf(f,";\n; Compiled Sprite Bitmap \n;\n\n\tIDEAL\n\t\tP386N\n\n");
  134.     fprintf(f,"Map_Mask\t\tEQU\t\t2\n");
  135.     fprintf(f,"Sequencer_Address_Port\t\tEQU\t\t03c4h\n\n");
  136.     fprintf(f,"SEGMENT\t\tCompiled_Sprite_Segment PARA PUBLIC USE16 'CODE'\n");
  137.     fprintf(f,"\t\tASSUME\t\tCS:Compiled_Sprite_Segment\n");
  138.     return f;
  139. } /* open_out() */
  140.  
  141.  
  142. /*---------------------------------------------------------------------------
  143.     Emit a 16 bit copy of sprite data to screen
  144. -----------------------------------------------------------------------------*/
  145.  
  146. void emit32(unsigned long *value)
  147. {
  148.     if ((*value != eax_contents) || (eax_dirty))
  149.         fprintf(cbm_file,"\t\tMOV\t\tEAX,0%Flxh\n",*value);
  150.     fprintf(cbm_file,"\t\tSTOSD\n");
  151.     eax_contents = *value;
  152.     eax_dirty = FALSE; 
  153.     sprite_byte+=4;     
  154. } /* emit32() */
  155.  
  156. /*---------------------------------------------------------------------------
  157.     Emit a 16 bit copy of sprite data to screen
  158. -----------------------------------------------------------------------------*/
  159.  
  160. void emit16(unsigned int *value)
  161. {
  162.     eax_dirty = TRUE;
  163.     fprintf(cbm_file,"\t\tMOV\t\tAX,0%Fxh\n",*value);
  164.     fprintf(cbm_file,"\t\tSTOSW\n");
  165.     sprite_byte+=2;
  166. } /* emit16() */
  167.  
  168. /*---------------------------------------------------------------------------
  169.     Emit an 8 bit copy of sprite data to screen
  170. -----------------------------------------------------------------------------*/
  171.  
  172. void emit8(unsigned char *value)
  173. {
  174.     eax_dirty = TRUE;
  175.     fprintf(cbm_file,"\t\tMOV\t\tAL,0%Fxh\n",(unsigned int) *value);
  176.     fprintf(cbm_file,"\t\tSTOSB\n");
  177.     sprite_byte++;
  178. } /* emit8() */
  179.  
  180. /*---------------------------------------------------------------------------
  181.     Emit an immediate addition to pointer to screen data
  182. -----------------------------------------------------------------------------*/
  183.  
  184.  
  185. void emitadd(unsigned int value)
  186. {
  187.     fprintf(cbm_file,"\t\tADD\t\tDI,0%Fxh\n",value);
  188.     sprite_byte += value;
  189.     lbm_byte += value;
  190. } /* emitadd() */
  191.  
  192. /*----------------------------------------------------------------------------
  193.     main procedure
  194. ----------------------------------------------------------------------------*/
  195.  
  196. void main(argc,argv)
  197. int argc;
  198. char far *argv[];
  199. {
  200.     int w,h;
  201.     
  202.     w = 0;
  203.     h = 0;
  204.     if (argc!=2)
  205.     {
  206.         fprintf(stderr,"usage :- cpcc <filename>\n");
  207.         exit(0); 
  208.     }
  209.                                                     /* ensure .PCC file type */
  210.     strcpy(pcc_name,remove_suffix(argv[1]));
  211.     strcat(pcc_name,".PCC");
  212.                                                     /* ensure .CBM file type */
  213.     strcpy(cbm_name,remove_suffix(argv[1]));
  214.     strcat(cbm_name,".CBM");
  215.  
  216. /*----------------------------------------------------------------------------
  217.     Read in the .PCC file
  218. ----------------------------------------------------------------------------*/
  219.  
  220.     pcc_size = get_file_size(pcc_name);
  221.  
  222.     if (pcc_size==0)
  223.     {
  224.         fprintf(stderr,"could not open %Fs.PCC\n",argv[1]);
  225.         exit(0);
  226.     }
  227.  
  228.     file_buffer = farmalloc((unsigned long)pcc_size);
  229.     if (get_file(pcc_name,file_buffer)==0)
  230.     {
  231.         fprintf(stderr,"error reading %Fs.PCC\n",argv[1]);
  232.         exit(0);
  233.     }   
  234.  
  235. /*----------------------------------------------------------------------------
  236.     Copy the .PCC buffer to the linear bit map (lbm) buffer expanding RLE
  237. ----------------------------------------------------------------------------*/
  238.  
  239.     pcc_buffer = (pcc_header *) file_buffer;
  240.     lbm_size = (pcc_buffer->x2 + 2) * 
  241.                (pcc_buffer->y2 + 2);                
  242.     
  243.     if ((lbm_buffer = (lbm_header *) farmalloc(lbm_size)) == NULL)
  244.     {
  245.         printf("malloc faliure\n");
  246.         exit(0);
  247.     }
  248.     
  249.     lbm_buffer->width = ((unsigned int) pcc_buffer->x2);               
  250.     lbm_buffer->height = ((unsigned int) pcc_buffer->y2);
  251.     decode_pcx_buffer(((unsigned char far *)lbm_buffer)+4,pcc_buffer);
  252.  
  253. /*----------------------------------------------------------------------------
  254.     Fix the *very* irritating odd width bug in Deluxe Pain(t)
  255. ----------------------------------------------------------------------------*/
  256.  
  257.     sprite_width = pcc_buffer->x2;
  258.     sprite_height = pcc_buffer->y2;
  259. /*    if ((sprite_width & 1)==0)
  260.         fix_odd_width_bug(lbm_buffer);
  261. */
  262.         
  263. /*----------------------------------------------------------------------------
  264.     Create four bit planes
  265. ----------------------------------------------------------------------------*/
  266.  
  267.     for(sprite_plane=0; sprite_plane<4; sprite_plane++)
  268.     {
  269.         if ((sprite_planes[sprite_plane] = farmalloc(lbm_size)) == NULL)
  270.         {
  271.             fprintf(stderr,"malloc faliure\n");
  272.             exit(0);
  273.         };
  274.         setmem(sprite_planes[sprite_plane],lbm_size,0);
  275.         plane_width[sprite_plane] = separate_sprite_plane( lbm_buffer,
  276.                                            sprite_planes[sprite_plane],
  277.                                            sprite_plane );
  278.     }   
  279.     
  280.  
  281. /*----------------------------------------------------------------------------
  282.     Write out assembled instructions to output file 
  283. ----------------------------------------------------------------------------*/
  284.  
  285.     cbm_file = open_out(cbm_name);
  286.  
  287.     fprintf(cbm_file,"\t\tGLOBAL\t%Fs_sprite:FAR\n",remove_suffix(argv[1]));
  288.     fprintf(cbm_file,"\t\tPROC\t\t%Fs_sprite FAR\n",remove_suffix(argv[1]));    
  289.     fprintf(cbm_file,"\t\tARG\tVideo_Address:WORD,Plane:WORD =ArgLen\n");
  290.     
  291.     fprintf(cbm_file,"\t\tP386N\n");
  292.     fprintf(cbm_file,"\t\tENTER\t\t0,0\n");
  293.     fprintf(cbm_file,"\t\tPUSH\t\tES\n\t\tPUSH\t\tEDI\n\t\tPUSH\t\tSI\n\t\tPUSH\t\tAX\n");
  294.     fprintf(cbm_file,"\t\tMOV\t\tAX,0a000h\n\t\tMOV\t\tES,AX\n");
  295.     fprintf(cbm_file,"\t\tMOVZX\t\tEDI,[Video_Address]\n");
  296.  
  297.     for(sprite_plane=0;sprite_plane<4;sprite_plane++)
  298.     {
  299.         /* plane by plane */
  300.         fprintf(cbm_file,"; ** plane #%u\n",sprite_plane);
  301.         fprintf(cbm_file,"\t\tMOV\t\tAX,[Plane]\n");
  302.         fprintf(cbm_file,"\t\tMOV\t\tSI,AX\n");
  303.         fprintf(cbm_file,"\t\tMOV\t\tDX,Sequencer_Address_Port\n");
  304.         fprintf(cbm_file,"\t\tMOV\t\tAH,[BYTE CS:@@Map_Mask_Lookup+SI]\n");
  305.         fprintf(cbm_file,"\t\tMOV\t\tAL,Map_Mask\n");
  306.         fprintf(cbm_file,"\t\tOUT\t\tDX,AX\n");
  307.         fprintf(cbm_file,"\t\tPUSH\t\tEDI\n");
  308.         sprite_byte = sprite_planes[sprite_plane];
  309.  
  310.         for(h=0; h<=sprite_height; h++)
  311.         {
  312.             fprintf(cbm_file,"; ROW #%u\n",h);
  313.             w = plane_width[sprite_plane];
  314.             while(w>0)
  315.             {
  316.                 if (w>1)
  317.                 {
  318.                     if    (w>3)
  319.                     {
  320.                         emit32(sprite_byte);
  321.                         w -= 4;
  322.                     } else
  323.                     {
  324.                         emit16(sprite_byte);
  325.                         w--;
  326.                         w--;
  327.                     }
  328.                 }
  329.                 else
  330.                 {
  331.                     emit8(sprite_byte);
  332.                     w--;
  333.                 }
  334.             }
  335.  
  336.             if (h != sprite_height)
  337.             {
  338.                 fprintf(cbm_file,"\t\tADD\t\tDI,%d\n",
  339.                         80-plane_width[sprite_plane]); 
  340.             }
  341.         }   
  342.  
  343.         fprintf(cbm_file,"\t\tPOP\t\tEDI\n");    
  344.         if (sprite_plane!=3)
  345.         {        
  346.             fprintf(cbm_file,"\t\tINC\t\t[Plane]\n");     
  347.             fprintf(cbm_file,"\t\tAND\t\t[Plane],3\n");
  348.             fprintf(cbm_file,"\t\tJNZ\t\tSHORT @@%u\n",sprite_plane);
  349.             fprintf(cbm_file,"\t\tINC\t\tEDI\n");
  350.             fprintf(cbm_file,"@@%u:\n",sprite_plane);
  351.         }
  352.     }
  353.     fprintf(cbm_file,"\t\tP386N\n");
  354.     fprintf(cbm_file,"\t\tPOP\t\tAX\n\t\tPOP\t\tSI\n\t\t\n\t\tPOP\t\tEDI\nPOP\t\tES\n");    
  355.     fprintf(cbm_file,"\t\tLEAVE\n");
  356.     fprintf(cbm_file,"\t\tRET\t\tArgLen\n");
  357.     fprintf(cbm_file,"@@Map_Mask_Lookup:\n\t\tdb\t01\n\t\tdb\t02\n\t\tdb\t04\n\t\tdb\t08\n");
  358.     fprintf(cbm_file,"ENDP\t\t%Fs_sprite\n",remove_suffix(argv[1]));    
  359.     fprintf(cbm_file,"\n\t\tENDS\n");
  360.     fclose(cbm_file);
  361.     printf("Compilation of %Fs done.\n",strupr(cbm_name));  
  362.  
  363.     exit(0);
  364. } /* main() */ 
  365.